package org.crystalrange.documents.web;

import org.apache.commons.lang3.StringUtils;
import org.crystalrange.documents.model.DocumentCategory;
import org.crystalrange.documents.model.DocumentType;
import org.crystalrange.model.User;
import org.crystalrange.searching.SearchOperatorListitemRenderer;
import org.crystalrange.searching.SearchOperators;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
import org.zkoss.zul.Bandbox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

import com.googlecode.genericdao.search.Filter;
import com.googlecode.genericdao.search.Search;

public class DocumentSearchController extends GenericForwardComposer {

	protected Listbox sortOperatorTitle;
	protected Listbox sortOperatorSubtitle;
	protected Listbox sortOperatorDescription;
	protected Listbox sortOperatorCopyright;
	protected Listbox sortOperatorDocumentType;
	protected Listbox sortOperatorDocumentCategory;
	protected Listbox sortOperatorDocumentLockedby;
	protected Search searchDocument;
	protected Textbox textboxTitle;
	protected Textbox textboxSubtitle;
	protected Textbox textboxDescription;
	protected Textbox textboxCopyright;
	protected Bandbox bandboxDocumentType;
	protected Bandbox bandboxDocumentCategory;
	protected Bandbox bandboxDocumentLockedby;
	protected DocumentType selectedDocumentType;
	protected DocumentCategory selectedDocumentCategory;
	protected User selectedUser;
	protected AnnotateDataBinder binder;

	public Search getSearchDocument() {
		return searchDocument;
	}

	public void setSearchDocument(Search searchDocument) {
		this.searchDocument = searchDocument;
	}

	public DocumentType getSelectedDocumentType() {
		return selectedDocumentType;
	}

	public void setSelectedDocumentType(DocumentType selectedDocumentType) {
		this.selectedDocumentType = selectedDocumentType;
	}

	public DocumentCategory getSelectedDocumentCategory() {
		return selectedDocumentCategory;
	}

	public void setSelectedDocumentCategory(
			DocumentCategory selectedDocumentCategory) {
		this.selectedDocumentCategory = selectedDocumentCategory;
	}
	
	public User getSelectedUser() {
		return selectedUser;
	}

	public void setSelectedUser(User selectedUser) {
		this.selectedUser = selectedUser;
	}

	@Override
	public void doAfterCompose(Component component) throws Exception {
		super.doAfterCompose(component);

		this.sortOperatorTitle.setModel(new ListModelList(SearchOperators
				.getAllOperators()));
		this.sortOperatorTitle
				.setItemRenderer(new SearchOperatorListitemRenderer());
		
		this.sortOperatorSubtitle.setModel(new ListModelList(SearchOperators
				.getAllOperators()));
		this.sortOperatorSubtitle
				.setItemRenderer(new SearchOperatorListitemRenderer());

		this.sortOperatorDescription.setModel(new ListModelList(SearchOperators
				.getAllOperators()));
		this.sortOperatorDescription
				.setItemRenderer(new SearchOperatorListitemRenderer());

		this.sortOperatorCopyright.setModel(new ListModelList(SearchOperators
				.getAllOperators()));
		this.sortOperatorCopyright
				.setItemRenderer(new SearchOperatorListitemRenderer());

		this.sortOperatorDocumentType.setModel(new ListModelList(
				SearchOperators.getAllOperators()));
		this.sortOperatorDocumentType
				.setItemRenderer(new SearchOperatorListitemRenderer());

		this.sortOperatorDocumentCategory.setModel(new ListModelList(
				SearchOperators.getAllOperators()));
		this.sortOperatorDocumentCategory
				.setItemRenderer(new SearchOperatorListitemRenderer());
		
		this.sortOperatorDocumentLockedby.setModel(new ListModelList(
				SearchOperators.getAllOperators()));
		this.sortOperatorDocumentLockedby
				.setItemRenderer(new SearchOperatorListitemRenderer());

		this.searchDocument = (Search) this.execution
				.getAttribute("searchDocument");

		if (this.searchDocument != null) {
			for (Filter filter : this.searchDocument.getFilters()) {
				if (filter.getProperty().equals("title")) {
					this.restoreOperator(this.sortOperatorTitle, filter);
					this.textboxTitle.setValue(filter.getValue().toString());
				} else if (filter.getProperty().equals("subtitle")) {
					this.restoreOperator(this.sortOperatorSubtitle, filter);
					this.textboxSubtitle.setValue(filter.getValue()
							.toString());
				} else if (filter.getProperty().equals("description")) {
					this.restoreOperator(this.sortOperatorDescription, filter);
					this.textboxDescription.setValue(filter.getValue()
							.toString());
				} else if (filter.getProperty().equals("copyright")) {
					this.restoreOperator(this.sortOperatorCopyright, filter);
					this.textboxCopyright
							.setValue(filter.getValue().toString());
				} else if (filter.getProperty().equals("documentType")) {
					this.restoreOperator(this.sortOperatorDocumentType, filter);
					this.selectedDocumentType = (DocumentType) filter
							.getValue();
				} else if (filter.getProperty().equals("documentCategory")) {
					this.restoreOperator(this.sortOperatorDocumentCategory,
							filter);
					this.selectedDocumentCategory = (DocumentCategory) filter
							.getValue();
				} else if (filter.getProperty().equals("lockedBy")) {
					this.restoreOperator(this.sortOperatorDocumentLockedby,
							filter);
					this.selectedUser = (User) filter
							.getValue();
				}
			}
		}

		component.setAttribute("controller", this);
	}

	private void restoreOperator(Listbox listbox, Filter filter) {
		if (filter.getOperator() == Filter.OP_EQUAL) {
			listbox.setSelectedIndex(1);
		} else if (filter.getOperator() == Filter.OP_NOT_EQUAL) {
			listbox.setSelectedIndex(2);
		} else if (filter.getOperator() == Filter.OP_LESS_THAN) {
			listbox.setSelectedIndex(3);
		} else if (filter.getOperator() == Filter.OP_GREATER_THAN) {
			listbox.setSelectedIndex(4);
		} else if (filter.getOperator() == Filter.OP_LESS_OR_EQUAL) {
			listbox.setSelectedIndex(5);
		} else if (filter.getOperator() == Filter.OP_GREATER_OR_EQUAL) {
			listbox.setSelectedIndex(6);
		} else if (filter.getOperator() == Filter.OP_ILIKE) {
			listbox.setSelectedIndex(7);
		}
	}

	public void onClick$buttonOk(Event event) throws Exception {
		this.searchDocument.getFilters().clear();

		if (StringUtils.isNotEmpty(this.textboxTitle.getText())) {
			Listitem item = this.sortOperatorTitle.getSelectedItem();
			if (item != null) {
				SearchOperators searchOperator = (SearchOperators) item
						.getValue();
				if (searchOperator.getSearchOperatorId() != -1) {
					this.searchDocument.addFilter(new Filter("title",
							this.textboxTitle.getValue(), searchOperator
									.getSearchOperatorId()));
				}
			}
		}
		
		if (StringUtils.isNotEmpty(this.textboxSubtitle.getText())) {
			Listitem item = this.sortOperatorSubtitle.getSelectedItem();
			if (item != null) {
				SearchOperators searchOperator = (SearchOperators) item
						.getValue();
				if (searchOperator.getSearchOperatorId() != -1) {
					this.searchDocument.addFilter(new Filter("subtitle",
							this.textboxSubtitle.getValue(), searchOperator
									.getSearchOperatorId()));
				}
			}
		}

		if (StringUtils.isNotEmpty(this.textboxDescription.getText())) {
			Listitem item = this.sortOperatorDescription.getSelectedItem();
			if (item != null) {
				SearchOperators searchOperator = (SearchOperators) item
						.getValue();
				if (searchOperator.getSearchOperatorId() != -1) {
					this.searchDocument.addFilter(new Filter("description",
							this.textboxDescription.getValue(), searchOperator
									.getSearchOperatorId()));
				}
			}
		}

		if (StringUtils.isNotEmpty(this.textboxCopyright.getText())) {
			Listitem item = this.sortOperatorCopyright.getSelectedItem();
			if (item != null) {
				SearchOperators searchOperator = (SearchOperators) item
						.getValue();
				if (searchOperator.getSearchOperatorId() != -1) {
					this.searchDocument.addFilter(new Filter("copyright",
							this.textboxCopyright.getValue(), searchOperator
									.getSearchOperatorId()));
				}
			}
		}

		if (StringUtils.isNotEmpty(this.bandboxDocumentType.getText())) {
			Listitem item = this.sortOperatorDocumentType.getSelectedItem();
			if (item != null) {
				SearchOperators searchOperator = (SearchOperators) item
						.getValue();
				if (searchOperator.getSearchOperatorId() != -1) {
					this.searchDocument.addFilter(new Filter("documentType",
							this.selectedDocumentType, searchOperator
									.getSearchOperatorId()));
				}
			}
		}

		if (StringUtils.isNotEmpty(this.bandboxDocumentCategory.getText())) {
			Listitem item = this.sortOperatorDocumentCategory.getSelectedItem();
			if (item != null) {
				SearchOperators searchOperator = (SearchOperators) item
						.getValue();
				if (searchOperator.getSearchOperatorId() != -1) {
					this.searchDocument.addFilter(new Filter(
							"documentCategory", this.selectedDocumentCategory,
							searchOperator.getSearchOperatorId()));
				}
			}
		}
		
		if (StringUtils.isNotEmpty(this.bandboxDocumentLockedby.getText())) {
			Listitem item = this.sortOperatorDocumentLockedby.getSelectedItem();
			if (item != null) {
				SearchOperators searchOperator = (SearchOperators) item
						.getValue();
				if (searchOperator.getSearchOperatorId() != -1) {
					this.searchDocument.addFilter(new Filter(
							"lockedBy", this.selectedUser,
							searchOperator.getSearchOperatorId()));
				}
			}
		}

		this.execution.setAttribute("searchDocument", this.searchDocument);
		this.execution.setAttribute("result", "ok");
		this.self.detach();
	}

	public void onClick$buttonCancel(Event event) throws Exception {
		this.execution.setAttribute("searchDocument", null);
		this.execution.setAttribute("result", "cancel");
		this.self.detach();
	}

	public void onOpen$bandboxDocumentType(Event event) throws Exception {
		Window window = (Window) this.execution.createComponents(
				"~./zul/html/documentTypeSelect.zul", null, null);
		window.setParent(self);
		window.doModal();

		if (this.execution.getAttribute("result") == "ok") {
			this.selectedDocumentType = (DocumentType) this.execution
					.getAttribute("selectedDocumentType");
		}

		this.binder.loadAll();
	}

	public void onOpen$bandboxDocumentCategory(Event event) throws Exception {
		Window window = (Window) this.execution.createComponents(
				"~./zul/html/documentCategorySelect.zul", null, null);
		window.setParent(self);
		window.doModal();

		if (this.execution.getAttribute("result") == "ok") {
			this.selectedDocumentCategory = (DocumentCategory) this.execution
					.getAttribute("selectedDocumentCategory");
		}

		this.binder.loadAll();
	}
	
	public void onOpen$bandboxDocumentLockedby(Event event) throws Exception {
		Window window = (Window) this.execution.createComponents(
				"~./zul/html/userSelect.zul", null, null);
		window.setParent(self);
		window.doModal();

		if (this.execution.getAttribute("result") == "ok") {
			this.selectedUser = (User) this.execution
					.getAttribute("selectedUser");
		}

		this.binder.loadAll();
	}
}
